package com.mm.update.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

public class EncryptUtil {
    private static final String ALGORITHM = "AES";
    private static final int KEY_SIZE = 128;
    private static final int TIMESTAMP_LENGTH = 8;

    private static String key = "vos";
    public static SecretKey generateKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(KEY_SIZE, new SecureRandom());
        return keyGenerator.generateKey();
    }

    public static byte[] encrypt(String data, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        long timestamp = System.currentTimeMillis();
        byte[] timestampBytes = longToBytes(timestamp);
        byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
        byte[] combinedData = new byte[timestampBytes.length + dataBytes.length];
        System.arraycopy(timestampBytes, 0, combinedData, 0, timestampBytes.length);
        System.arraycopy(dataBytes, 0, combinedData, timestampBytes.length, dataBytes.length);
        return cipher.doFinal(combinedData);
    }

    public static String decrypt(byte[] data, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decryptedData = cipher.doFinal(data);
        long timestamp = bytesToLong(decryptedData, 0);
        if (System.currentTimeMillis() - timestamp > 30 * 60 * 1000) {
            throw new Exception("Decryption failed: more than 30 minutes have passed");
        }
        byte[] originalData = new byte[decryptedData.length - TIMESTAMP_LENGTH];
        System.arraycopy(decryptedData, TIMESTAMP_LENGTH, originalData, 0, originalData.length);
        return new String(originalData, StandardCharsets.UTF_8);
    }

    private static byte[] longToBytes(long value) {
        byte[] bytes = new byte[TIMESTAMP_LENGTH];
        for (int i = 0; i < TIMESTAMP_LENGTH; i++) {
            bytes[i] = (byte) (value >>> (8 * i));
        }
        return bytes;
    }

    private static long bytesToLong(byte[] bytes, int offset) {
        long value = 0;
        for (int i = 0; i < TIMESTAMP_LENGTH; i++) {
            value |= ((long) bytes[offset + i] & 0xFFL) << (8 * i);
        }
        return value;
    }


    public static void main(String[] args) throws Exception {
        String data = "Hello, world!";
        SecretKey key = EncryptUtil.generateKey();
        byte[] encryptedData = EncryptUtil.encrypt(data, key);
        String encryptedDataBase64 = Base64.getEncoder().encodeToString(encryptedData);
        System.out.println("Encrypted data: " + encryptedDataBase64);
    }


}
